package com.xiaozhi.utils;

import com.xiaozhi.entity.HealthAnalytics;
import com.itheima.java.ai.langchin4j.entity.VitalSigns;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 健康分析优化工具类
 * 提供高效的数据分析算法和缓存策略
 *
 * @author xiaozhi
 * @since 2024-01-15
 */
@Component
public class HealthAnalysisOptimizer {

    private static final Logger log = LoggerFactory.getLogger(HealthAnalysisOptimizer.class);

    // 分析结果缓存
    private final Map<String, CachedAnalysisResult> analysisCache = new ConcurrentHashMap<>();
    
    // 缓存过期时间（毫秒）
    private static final long CACHE_EXPIRY_TIME = 30 * 60 * 1000; // 30分钟
    
    // 最大缓存大小
    private static final int MAX_CACHE_SIZE = 1000;

    /**
     * 缓存的分析结果
     */
    private static class CachedAnalysisResult {
        private final Map<String, Object> result;
        private final long timestamp;
        
        public CachedAnalysisResult(Map<String, Object> result) {
            this.result = result;
            this.timestamp = System.currentTimeMillis();
        }
        
        public boolean isExpired() {
            return System.currentTimeMillis() - timestamp > CACHE_EXPIRY_TIME;
        }
        
        public Map<String, Object> getResult() {
            return result;
        }
    }

    /**
     * 优化的生命体征分析
     * @param vitalSignsList 生命体征数据列表
     * @return 分析结果
     */
    public Map<String, Object> optimizedVitalSignsAnalysis(List<VitalSigns> vitalSignsList) {
        try {
            // 生成缓存键
            String cacheKey = generateCacheKey("vital_signs", vitalSignsList);
            
            // 检查缓存
            CachedAnalysisResult cached = analysisCache.get(cacheKey);
            if (cached != null && !cached.isExpired()) {
                log.debug("使用缓存的分析结果: {}", cacheKey);
                return cached.getResult();
            }
            
            // 执行分析
            Map<String, Object> result = performVitalSignsAnalysis(vitalSignsList);
            
            // 存储到缓存
            if (analysisCache.size() < MAX_CACHE_SIZE) {
                analysisCache.put(cacheKey, new CachedAnalysisResult(result));
            }
            
            return result;
        } catch (Exception e) {
            log.error("生命体征分析失败", e);
            return createErrorResult("生命体征分析失败: " + e.getMessage());
        }
    }

    /**
     * 执行生命体征分析
     */
    private Map<String, Object> performVitalSignsAnalysis(List<VitalSigns> vitalSignsList) {
        Map<String, Object> result = new HashMap<>();
        
        if (vitalSignsList.isEmpty()) {
            return createErrorResult("没有可分析的生命体征数据");
        }
        
        // 基础统计
        result.put("statistics", calculateBasicStatistics(vitalSignsList));
        
        // 趋势分析
        result.put("trends", analyzeTrends(vitalSignsList));
        
        // 异常检测
        result.put("anomalies", detectAnomalies(vitalSignsList));
        
        // 风险评估
        result.put("riskAssessment", assessRisk(vitalSignsList));
        
        result.put("totalRecords", vitalSignsList.size());
        result.put("analysisTime", LocalDateTime.now());
        result.put("success", true);
        
        return result;
    }

    /**
     * 计算基础统计信息
     */
    private Map<String, Object> calculateBasicStatistics(List<VitalSigns> vitalSignsList) {
        Map<String, Object> stats = new HashMap<>();
        
        // 收缩压统计
        List<Integer> systolicValues = vitalSignsList.stream()
                .filter(vs -> vs.getSystolicBp() != null)
                .map(vs -> vs.getSystolicBp())
                .collect(Collectors.toList());
        
        // 舒张压统计
        List<Integer> diastolicValues = vitalSignsList.stream()
                .filter(vs -> vs.getDiastolicBp() != null)
                .map(vs -> vs.getDiastolicBp())
                .collect(Collectors.toList());

        if (!systolicValues.isEmpty()) {
            stats.put("systolic", calculateValueStats(systolicValues));
        }
        
        if (!diastolicValues.isEmpty()) {
            stats.put("diastolic", calculateValueStats(diastolicValues));
        }
        
        return stats;
    }

    /**
     * 计算数值统计
     */
    private Map<String, Object> calculateValueStats(List<Integer> values) {
        Map<String, Object> stats = new HashMap<>();
        
        if (values.isEmpty()) {
            return stats;
        }
        
        // 基础统计
        double avg = values.stream().mapToInt(Integer::intValue).average().orElse(0.0);
        int min = values.stream().mapToInt(Integer::intValue).min().orElse(0);
        int max = values.stream().mapToInt(Integer::intValue).max().orElse(0);
        
        stats.put("average", Math.round(avg * 100.0) / 100.0);
        stats.put("min", min);
        stats.put("max", max);
        stats.put("count", values.size());
        
        return stats;
    }

    /**
     * 趋势分析
     */
    private Map<String, Object> analyzeTrends(List<VitalSigns> vitalSignsList) {
        Map<String, Object> trends = new HashMap<>();
        
        // 简化的趋势分析
        if (vitalSignsList.size() < 2) {
            trends.put("status", "数据不足，无法分析趋势");
            return trends;
        }
        
        // 按时间排序
        List<VitalSigns> sortedList = vitalSignsList.stream()
                .sorted(Comparator.comparing(VitalSigns::getRecordTime))
                .collect(Collectors.toList());
        
        VitalSigns first = sortedList.get(0);
        VitalSigns last = sortedList.get(sortedList.size() - 1);
        
        // 血压趋势
        if (first.getSystolicBp() != null && last.getSystolicBp() != null) {
            int systolicChange = last.getSystolicBp() - first.getSystolicBp();
            trends.put("systolicTrend", systolicChange > 0 ? "上升" : systolicChange < 0 ? "下降" : "稳定");
            trends.put("systolicChange", systolicChange);
        }
        
        if (first.getDiastolicBp() != null && last.getDiastolicBp() != null) {
            int diastolicChange = last.getDiastolicBp() - first.getDiastolicBp();
            trends.put("diastolicTrend", diastolicChange > 0 ? "上升" : diastolicChange < 0 ? "下降" : "稳定");
            trends.put("diastolicChange", diastolicChange);
        }
        
        return trends;
    }

    /**
     * 异常检测
     */
    private List<String> detectAnomalies(List<VitalSigns> vitalSignsList) {
        List<String> anomalies = new ArrayList<>();
        
        for (VitalSigns vs : vitalSignsList) {
            // 血压异常检测
            if (vs.getSystolicBp() != null) {
                if (vs.getSystolicBp() > 180) {
                    anomalies.add("严重高收缩压: " + vs.getSystolicBp() + " mmHg");
                } else if (vs.getSystolicBp() > 140) {
                    anomalies.add("高收缩压: " + vs.getSystolicBp() + " mmHg");
                } else if (vs.getSystolicBp() < 90) {
                    anomalies.add("低收缩压: " + vs.getSystolicBp() + " mmHg");
                }
            }
            
            if (vs.getDiastolicBp() != null) {
                if (vs.getDiastolicBp() > 110) {
                    anomalies.add("严重高舒张压: " + vs.getDiastolicBp() + " mmHg");
                } else if (vs.getDiastolicBp() > 90) {
                    anomalies.add("高舒张压: " + vs.getDiastolicBp() + " mmHg");
                } else if (vs.getDiastolicBp() < 60) {
                    anomalies.add("低舒张压: " + vs.getDiastolicBp() + " mmHg");
                }
            }
        }
        
        return anomalies;
    }

    /**
     * 风险评估
     */
    private Map<String, Object> assessRisk(List<VitalSigns> vitalSignsList) {
        Map<String, Object> risk = new HashMap<>();
        
        int highRiskCount = 0;
        int totalCount = vitalSignsList.size();
        
        for (VitalSigns vs : vitalSignsList) {
            boolean isHighRisk = false;
            
            // 高血压风险
            if (vs.getSystolicBp() != null && vs.getSystolicBp() > 140) {
                isHighRisk = true;
            }
            if (vs.getDiastolicBp() != null && vs.getDiastolicBp() > 90) {
                isHighRisk = true;
            }
            
            if (isHighRisk) {
                highRiskCount++;
            }
        }
        
        double riskPercentage = totalCount > 0 ? (highRiskCount * 100.0 / totalCount) : 0;
        String riskLevel = riskPercentage > 50 ? "高风险" : riskPercentage > 20 ? "中风险" : "低风险";
        
        risk.put("level", riskLevel);
        risk.put("percentage", Math.round(riskPercentage * 100.0) / 100.0);
        risk.put("highRiskCount", highRiskCount);
        risk.put("totalCount", totalCount);
        
        return risk;
    }

    /**
     * 生成缓存键
     */
    private String generateCacheKey(String type, List<VitalSigns> data) {
        StringBuilder sb = new StringBuilder(type);
        sb.append("_").append(data.size());
        if (!data.isEmpty()) {
            sb.append("_").append(data.get(0).getUserId());
            sb.append("_").append(data.hashCode());
        }
        return sb.toString();
    }

    /**
     * 创建错误结果
     */
    private Map<String, Object> createErrorResult(String message) {
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("error", message);
        result.put("analysisTime", LocalDateTime.now());
        return result;
    }

    /**
     * 获取缓存统计信息
     */
    public Map<String, Object> getCacheStats() {
        Map<String, Object> stats = new HashMap<>();
        
        long currentTime = System.currentTimeMillis();
        long expiredCount = analysisCache.values().stream()
                .mapToLong(cached -> cached.isExpired() ? 1 : 0)
                .sum();
        
        stats.put("totalCacheSize", analysisCache.size());
        stats.put("expiredCacheCount", expiredCount);
        stats.put("activeCacheCount", analysisCache.size() - expiredCount);
        stats.put("maxCacheSize", MAX_CACHE_SIZE);
        stats.put("cacheUsagePercentage", 
            Math.round((double) analysisCache.size() / MAX_CACHE_SIZE * 100));
        stats.put("cacheExpiryTime", CACHE_EXPIRY_TIME);
        
        return stats;
    }

    /**
     * 清理过期缓存（方法名别名）
     */
    public void cleanupExpiredCache() {
        clearExpiredCache();
    }

    /**
     * 清理过期缓存
     */
    public void clearExpiredCache() {
        analysisCache.entrySet().removeIf(entry -> entry.getValue().isExpired());
        log.debug("清理过期缓存完成，当前缓存大小: {}", analysisCache.size());
    }

    /**
     * 清空所有缓存
     */
    public void clearAllCache() {
        analysisCache.clear();
        log.debug("清空所有缓存完成");
    }
}